<script setup>
import {h, reactive, ref, watch} from "vue";
import {addComment, deleteComment, frontGetCommentPage,} from "@/api/comment";
import TextOverflow from "@/components/TextOverflow/index.vue";
import ChildrenItem from "./ChildrenItem.vue";
import Loading from "@/components/Loading/Loading.vue";
import {user} from "@/store/index";
import {ElMessageBox, ElNotification} from "element-plus";
import {getCurrentTypeKey} from "../tool";
import {addFootprint} from "@/api/like";
import {containHTML, formatDateTime, getNoticeType} from "@/utils/tool";

const userStore = user();

const emits = defineEmits(["refresh"]);

const props = defineProps({
  active: {
    // 按最热/最新 排序
    type: String,
    default: "hot",
  },
  // 评论的类型 文章 article 说说 talk
  type: {
    type: String,
    default: () => {
    },
  },
  // 文章/说说 id
  id: {
    type: Number,
    default: () => {
    },
  },
});
const childrenRef = ref();
// 父级评论搜索参数
const params = reactive({
  pageNo: 1,
  pageSize: 5,
  orderBy: "",
  loading: false,
});
// 父级评论列表
const commentList = ref([]);
const commentTotal = ref(0);
// 获取父级评论
const getComment = async (type) => {
  params.loading = true;
  if (type === "clear") {
    params.pageNo = 1;
  }
  params[getCurrentTypeKey(props.type)] = props.id;
  const res = await frontGetCommentPage(params);
  if (res && res.code === 0) {
    const {list, total} = res.data;
    list.forEach((l) => {
      l.showApplyInput = false;
    });
    commentList.value = params.pageNo === 1 ? list : commentList.value.concat(list);
    commentTotal.value = total - 0;
  } else {
    ElNotification({
      offset: 60,
      title: "错误提示",
      message: h("div", {style: "color: #f56c6c; font-weight: 600;"}, res.message),
      type: getNoticeType(),
    });
  }
  params.loading = false;
};

// 加载更多的评论
const showMore = () => {
  params.pageNo++;
  getComment();
};

const currentApplyIndex = ref(0);

// 点赞
const like = async (item, index) => {
  let params = {
    footprintFor: 2,
    commentId: item.id
  };
  let res;
  // 查看点赞了没有，点赞了就进行取消点赞
  if (item.isLike) {
    params.footprint = 0;
    res = await addFootprint(params);
    if (res && res.code === 0) {
      commentList.value[index].isLike = false;
      commentList.value[index].thumbsUpTimes--;
      ElNotification({
        offset: 60,
        title: "提示",
        message: h("div", {style: "color: #7ec050; font-weight: 600;"}, "已取消点赞"),
        type: getNoticeType(),
      });
    }
  } else {
    params.footprint = 1;
    res = await addFootprint(params);
    if (res && res.code === 0) {
      commentList.value[index].isLike = true;
      commentList.value[index].thumbsUpTimes++;
      ElNotification({
        offset: 60,
        title: "提示",
        message: h("div", {style: "color: #7ec050; font-weight: 600;"}, "点赞成功"),
        type: getNoticeType(),
      });
    }
  }
};

const apply = (item, index) => {
  // 记录一下回复的是哪个主评论
  commentList.value[index].showApplyInput = true;
  currentApplyIndex.value = index;
  childrenRef.value[index].apply(item, "parent");
};

const close = (index) => {
  // 根据记录的主评论index来关闭那个主评论的输入框
  commentList.value[index].showApplyInput = false;
  currentApplyIndex.value = 0;
  childrenRef.value[index].closeComment();
};

const changeShowApplyInput = (val, index) => {
  commentList.value[index].showApplyInput = val;
};

// 关闭打开的输入框
const closeComment = () => {
  if (commentList.value.length) {
    childrenRef.value.forEach((v) => {
      v.closeComment();
    });
  }
};

const deleteOwnComment = (id) => {
  ElMessageBox.confirm("确认删除此条评论吗？子级评论也会被删除哦", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
  }).then(async () => {
    const res = await deleteComment(id);
    if (res && res.code === 0) {
      ElNotification({
        offset: 60,
        title: "提示",
        message: h("div", {style: "color: #7ec050; font-weight: 600;"}, "删除成功"),
        type: getNoticeType(),
      });
      await getComment("clear");
      emits("refresh");
    }
  });
};

const publish = async (item) => {
  const data = {
    commentContent: item.commentContent,
    parentId: item.parentId,
  };
  data[getCurrentTypeKey(props.type)] = props.id;

  const res = await addComment(data);
  if (res.code === 0) {
    ElNotification({
      offset: 60,
      title: "提示",
      message: h("div", {style: "color: #7ec050; font-weight: 600;"}, "评论成功"),
      type: getNoticeType(),
    });
    params.pageNo = 1;
    childrenRef.value[currentApplyIndex.value].getComment("clear");
    currentApplyIndex.value = 0;
    emits("refresh");
  }
};

watch(
    () => props.type,
    () => {
      Object.assign(params, {
        orderBy: props.active,
      });
      getComment();
    },
    {
      immediate: true,
    }
);
watch(
    () => props.active,
    (newV) => {
      Object.assign(params, {
        orderBy: newV,
        pageNo: 1,
      });
      getComment();
    },
    {}
);

defineExpose({
  getComment,
  closeComment,
});
</script>

<template>
  <div class="comment-parent">
    <template v-if="commentList.length">
      <div
          class="!mt-[0.5rem] animate__animated animate__fadeIn"
          v-for="(comment, index) in commentList"
          :key="index"
      >
        <div class="flex justify-start items-start">
          <div class="avatar-box">
            <el-avatar class="avatar" :src="comment.userAvatar">{{ comment.userNickname }}</el-avatar>
          </div>
          <div class="right !w-[100%]">
            <div class="cursor-pointer">
              {{ comment.userNickname }}
              <span v-if="comment.userId === 1" class="up">UP</span>
            </div>
            <div id="comment-content" class="!mt-[1rem]">
              <span v-if="containHTML(comment.commentContent)" v-html="comment.commentContent"></span>
              <TextOverflow
                  v-else
                  class="content"
                  :key="comment.id"
                  :text="comment.commentContent"
                  :maxLines="3"
                  :font-size="16"
              >
                <template v-slot:default="{ clickToggle, expanded }">
                  <span @click="clickToggle" class="btn">
                    {{ expanded ? "收起" : "展开" }}
                  </span>
                </template>
              </TextOverflow>
            </div>
            <div class="!mt-[0.5rem]">
              <span class="!mr-[1rem] ip">{{ `IP: ${comment.creatorCity}` }}</span>
              <span
                  :class="[
                  'thumbs',
                  '!mr-[1rem]',
                  'iconfont',
                  'icon-icon1',
                  comment.isLike ? 'like-active' : '',
                ]"
                  @click="like(comment, index)"
              >
                <span class="!ml-[0.5rem]">{{ comment.thumbsUpTimes }}</span>
              </span>
              <span class="!mr-[1rem] apply cursor-pointer" @click="apply(comment, index)"
              >回复</span
              >
              <span
                  v-if="comment.showApplyInput"
                  class="!mr-[1rem] close cursor-pointer"
                  @click="close(index)"
              >关闭</span
              >
              <span
                  class="!mr-[1rem] delete cursor-pointer"
                  v-if="
                  userStore.getUserInfo.id === comment.userId && comment.userType === 1
                "
                  @click="deleteOwnComment(comment.id)"
              >删除</span
              >
            </div>
            <div class="!mt-[0.5rem]">{{ formatDateTime(comment.createTime) }}</div>
            <ChildrenItem
                class="!mt-[1.5rem]"
                ref="childrenRef"
                :type="props.type"
                :id="id"
                :parent-id="comment.id"
                @parentApply="publish"
                @refresh="emits('refresh')"
                @changeShowApplyInput="(val) => changeShowApplyInput(val, index)"
            />
          </div>
        </div>
      </div>
    </template>

    <Loading :size="32" v-if="params.loading"/>
    <div v-else-if="commentTotal > commentList.length" class="show-more" @click="showMore">
      展开更多
    </div>
    <div v-else class="h-[48px]"></div>
  </div>
</template>

<style lang="scss" scoped>
.comment-parent {
  width: 100%;
}

.active {
  color: var(--primary);
}

.icon-icon1 {
  cursor: pointer;
}

.thumbs {
  word-break: keep-all;
  font-size: 1rem;
}

.apply {
  word-break: keep-all;
  font-size: 1rem;
  color: var(--md-active);
}

.apply:hover {
  color: var(--primary);
}

.close {
  color: var(--top);
  word-break: keep-all;
  font-size: 1rem;

  &:hover {
    color: var(--hot-color);
  }
}

.content-apply {
  font-size: 0.8rem;
}

.delete {
  word-break: keep-all;
  font-size: 1rem;
  color: var(--top);

  &:hover {
    color: var(--hot-color);
  }
}

.ip {
  font-size: 0.8rem;
  display: inline-block;
}

.show-more {
  cursor: pointer;
  margin-top: 3px;
  font-size: 0.8rem;

  &:hover {
    color: var(--primary);
  }
}

.like-active {
  color: var(--primary);
  transform: scale(1.05);
}

.up {
  margin-left: 0.5rem;
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--hot-color);
}

.btn {
  color: var(--primary);
  cursor: pointer;
}

@media screen and (max-width: 768px) {
  .right {
    margin-left: 10px;
  }

  .avatar-box {
    width: 32px;
    height: 32px;
  }
  .avatar {
    width: 32px;
    height: 32px;
  }
}

@media screen and (min-width: 768px) {
  .avatar-box {
    width: 45px;
    height: 45px;
  }
  .avatar {
    width: 45px;
    height: 45px;
  }
  .right {
    margin-left: 10px;
  }
}
</style>
